package com.company.Lab3;

import java.util.Scanner;

public class AditiveMethod {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        double[][] mainMatrix;
        double[][] utilityMatrix;
        double[] utilitySum;
        double[] maxValuesOnColumn;
        double[] minValuesOnColumn;
        String[] priority;
        int r, c;
        double finalValue;

        System.out.print("Introduceti numarul de randuri : ");
        r = scanner.nextInt();
        System.out.print("Introduceti numarul de coloane : ");
        c = scanner.nextInt();

//        init arrays
        mainMatrix = new double[r][c];
        utilityMatrix = new double[r][c];
        utilitySum = new double[r];
        maxValuesOnColumn = new double[c];
        minValuesOnColumn = new double[c];
        priority = new String[c];

//        read arrays from keyboard
        System.out.println("Introduceti matricea generala : ");
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                System.out.print("[" + i + "][" + j + "] : ");
                mainMatrix[i][j] = scanner.nextDouble();
            }
        }
        System.out.println("Introduceti prioritatile :  (max sau min valori)");
        for (int i = 0; i < c; i++) {
            System.out.print("Prioritatea [" + i + "] : ");
            if (i == 0) {
                scanner.nextLine();
            }
            priority[i] = scanner.nextLine();
        }
//        Logic
//        calc pre data
        maxValuesOnColumn = calcMaxOnColumn(mainMatrix, r, c); // calc maximum from column
        minValuesOnColumn = calcMinOnColumn(mainMatrix, r, c); // calc minimum from column
//        calc utility matrix
        utilityMatrix = calcUtilityMatrix(mainMatrix, maxValuesOnColumn, minValuesOnColumn, priority, r, c);
//        calc sum for utility matrix (each row)
        utilitySum = calcSumForRowBidimensional(utilityMatrix, r, c);
//        calc max from utilityMax array
        finalValue = calcMaxForRow(utilitySum, r);
        System.out.println("Decizia optima : " + finalValue);

    }

    public static double[] calcMaxOnColumn(final double[][] array, final int r, final int c) {
        double[] maxArray = new double[c];
        double maximum = 0;
        for (int i = 0; i < c; i++) {
            maximum = array[0][i];
            for (int j = 0; j < r; j++) {
                maximum = Math.max(maximum, array[j][i]);
            }
            maxArray[i] = maximum;
        }
        return maxArray;
    }

    public static double[] calcMinOnColumn(final double[][] array, final int r, final int c) {
        double[] minArray = new double[c];
        double minimum = 0;
        for (int i = 0; i < c; i++) {
            minimum = array[0][i];
            for (int j = 0; j < r; j++) {
                minimum = Math.min(minimum, array[j][i]);
            }
            minArray[i] = minimum;
        }
        return minArray;
    }

    public static double[] calcSumForRowBidimensional(final double[][] array, final int r, final int c) {
        double[] sumArray = new double[r];
        double sum;
        for (int i = 0; i < r; i++) {
            sum = 0;
            for (int j = 0; j < c; j++) {
                sum += array[i][j];
            }
            sumArray[i] = sum;
        }
        return sumArray;
    }

    public static double calcMaxForRow(final double[] array, final int r) {
        double max = array[0];
        for (int i = 0; i < r; i++) {
            max = Math.max(max, array[i]);
        }
        return max;
    }

    public static double[][] calcUtilityMatrix(final double[][] main, final double[] maxValuesOnColumn
            , final double[] minValuesOnColumn, final String[] priority, final int r, final int c) {
        double[][] utility = new double[r][c];
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
//                logic for min case
                if (priority[j].equalsIgnoreCase("min")) {
                    utility[i][j] = (maxValuesOnColumn[j] - main[i][j]) / (maxValuesOnColumn[j] - minValuesOnColumn[j]);
                } // logic for min case
                else if (priority[j].equalsIgnoreCase("max")) {
                    utility[i][j] = (main[i][j] - minValuesOnColumn[j]) / (maxValuesOnColumn[j] - minValuesOnColumn[j]);
                }
            }
        }
        return utility;
    }
}
